package logic

import (
	"encoding/json"
	"fmt"
	"iot-base/auth/db"
	"iot-base/auth/model"
	"iot-base/auth/svc"
	types2 "iot-base/auth/types"
	"time"
)

type UserGroupLogic struct {
}

func NewUserGroupLogic() *UserGroupLogic {
	return &UserGroupLogic{}
}

// EditUserGroup 编辑用户角色.
func (l *UserGroupLogic) EditUserGroup(uid int64, groups []types2.UserGroups) error {
	_, err := svc.Dao.TUserGroup.DelGroupRole(uid, 0)
	if err != nil {
		return err
	}
	length := len(groups)
	if length == 0 {
		return nil
	}
	userGroup := make([]model.UserGroup, 0, length)
	for _, v := range groups {
		data := model.UserGroup{
			Uid:     uid,
			GroupId: v.GroupId,
			RoleId:  v.RoleId,
		}
		userGroup = append(userGroup, data)
	}
	// 清除缓存
	redis := db.NewRedis()
	redis.Del(fmt.Sprintf(db.KeyUserThingId+"#%v", uid))
	redis.Del(fmt.Sprintf(db.KeyUserGroup+"#%v", uid))
	return svc.Dao.TUserGroup.BatchSave(userGroup)
}

// FindUserGroup 查询用户拥有的组.
func (l *UserGroupLogic) FindUserGroup(uid int64) ([]model.AuthGroup, error) {
	return svc.Dao.TAuthGroup.GetUserGroup(uid)
}

// AddUserGroup 编辑用户角色.
func (l *UserGroupLogic) AddUserGroup(uid, groupId, roleId int64) (model.UserGroup, error) {
	userGroup := model.UserGroup{}
	_, err := svc.Dao.TUserGroup.DelGroupRole(uid, 0)
	if err != nil {
		return userGroup, err
	}
	userGroup.Uid = uid
	userGroup.GroupId = groupId
	userGroup.RoleId = roleId
	err = svc.Dao.TUserGroup.AddGroupRole(&userGroup)
	return userGroup, err
}

type Group model.UserGroup

func (l *UserGroupLogic) GetUserGroup(uid int64) ([]model.AuthGroup, error) {
	resp := make([]model.AuthGroup, 0)
	key := fmt.Sprintf(db.KeyUserGroup+"#%v", uid)
	redis := db.NewRedis()
	value, _ := redis.Get(key)
	if value != "" && value != db.Null {
		err := json.Unmarshal([]byte(value), &resp)
		if err != nil {
			return append([]model.AuthGroup{}, resp...), err
		} else {
			return resp, err
		}
	}
	// 查询用户拥有用的组
	resp, err := svc.Dao.TAuthGroup.GetUserGroup(uid)
	if err != nil {
		redis.Set(key, db.Null, time.Second*3)
		return make([]model.AuthGroup, 0), nil
	}
	if len(resp) == 0 {
		redis.Set(key, db.Null, time.Hour*1)
		return resp, err
	}
	b, _ := json.Marshal(resp)
	redis.Set(key, string(b), time.Hour*1)
	return resp, nil
}
